/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package net.silverfoxserver.core.socket;

import java.time.LocalTime;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import net.silverfoxserver.core.model.IUserModel;

/**
 *
 * @author ACER-FX
 */
public class OnlineUserManager {
    
    /** 
     * 默认百万在线
    */
    private int _maxOnlinePeople = 1000000;
    
     /** 

    */
    private ConcurrentHashMap _userList = new ConcurrentHashMap();
    
    //public final AppSession getSessionByAccountName(String accountName)
    public final String getSessionByAccountName(String accountName)    
    {
            if (hasUserByAccountName(accountName))
            {
                    String strIpPort = getUserByAccountName(accountName).getStrIpPort();

                    //return this.getSession(strIpPort);
                     
                    return strIpPort;
            }

            return null;
            
    }    
    
    
    public final IUserModel getUserByAccountName(String accountName)
    {
            //
            int count = this._userList.keySet().size();

            Object[] keysList;// = new Object[count];
            //this._userList.keySet().CopyTo(keysList, 0);
            keysList = this._userList.keySet().toArray();

            //
            int keysLen = keysList.length;

            for (int i = 0; i < keysLen; i++)
            {
                    IUserModel user = (IUserModel)this._userList.get(keysList[i]);

                    if (user.getAccountName().equals(accountName))
                    {
                            return user;
                    }
            }

            return null;
    } /** 
	 
	 
     @param accountName
     @return 
    */
    public final boolean hasUserByAccountName(String accountName)
    {
            //
            int count = this._userList.keySet().size();

            Object[] keysList;//new Object[count];
            //this._userList.keySet().CopyTo(keysList, 0);
            keysList = this._userList.keySet().toArray();

            //
            int keysLen = keysList.length;

            for (int i = 0; i < keysLen; i++)
            {
                    IUserModel user = (IUserModel)this._userList.get(keysList[i]);

                    if (null != user)
                    {
                            if (user.getAccountName().equals(accountName))
                            {
                                    return true;
                            }
                    }

            }

            return false;

    }
    
    /** 


     @param id
     @return 
    */
    public final boolean hasUserById(String id)
    {

            //
            int count = this._userList.keySet().size();

            Object[] keysList;// = new Object[count];
            //this._userList.keySet().CopyTo(keysList, 0);
            keysList = this._userList.keySet().toArray();                    
                    
            //
            int keysLen = keysList.length;

            for (int i = 0; i < keysLen; i++)
            {

                    IUserModel user = (IUserModel)this._userList.get(keysList[i]);

                    if (user.getId().equals(id))
                    {
                            return true;
                    }

            }

            return false;

    }
    
     /** 
     速度最快的方法
     调用前先使用hasUser方法

     @param strIpPort
     @return 
    */
    public final IUserModel getUser(String strIpPort)
    {
            return (IUserModel)this._userList.get(strIpPort);
    }
    
    /** 
	 
     @param id
     @return 
    */
    public final IUserModel getUserById(String id)
    {

            //
            int count = this._userList.keySet().size();

            Object[] keysList;// = new Object[count];
            //this._userList.keySet().CopyTo(keysList, 0);
            keysList = this._userList.keySet().toArray();
                    
            //
            int keysLen = keysList.length;

            for (int i = 0; i < keysLen; i++)
            {
                    IUserModel user = (IUserModel)this._userList.get(keysList[i]);

                    if (user.getId().equals(id))
                    {
                            return user;
                    }
            }

            return null;
    }
    
    /** 
     不可以直接返回_userList
     返回的是strIpPort字符串集合

     @return 
    */
    public final ArrayList<String> getUserList()
    {
            //
            int count = this._userList.keySet().size();

            Object[] keysList;// = new Object[count];
            //this._userList.keySet().CopyTo(keysList, 0);
            keysList = this._userList.keySet().toArray();

            //
            ArrayList<String> list = new ArrayList<>();

            //
            int keysLen = keysList.length;

            for (int i = 0; i < keysLen; i++)
            {
                    list.add(keysList[i].toString());
            }

            return list;

    }
    
    /** 
	 
	 
     @param isDead true为已长时间未收到心跳的用户
     @return 
    */
    public final java.util.ArrayList<String> getUserListByHeartBeat(boolean isDead)
    {
            //
            java.util.ArrayList<String> deadList = new java.util.ArrayList<>();
            java.util.ArrayList<String> healthList = new java.util.ArrayList<>();

            //
            int nowMinute = LocalTime.now().getMinute();

            //误差范围
            int range = 1;

            java.util.ArrayList<Integer> nowMinuteList = new java.util.ArrayList<>();
            nowMinuteList.add(nowMinute);

            int nowMinutePlus = nowMinute;
            int nowMinuteSub = nowMinute;

            int i;
            for (i = 0; i < range; i++)
            {
                    //
                    nowMinutePlus++;

                    if (nowMinutePlus > 59)
                    {
                            nowMinutePlus = 0;
                    }

                    nowMinuteList.add(nowMinutePlus);

                    //
                    nowMinuteSub--;

                    if (nowMinuteSub < 0)
                    {
                            nowMinuteSub = 59;
                    }

                    nowMinuteList.add(nowMinuteSub);

            }

            //
            int jLen = nowMinuteList.size();

            int count = this._userList.keySet().size();

            Object[] keysList;// = new Object[count];
            //this._userList.keySet().CopyTo(keysList, 0);
            keysList = this._userList.keySet().toArray();

            //foreach (object key in this._userList.Keys)
            for (i = 0; i < count; i++)
            {
                    Object key_ = keysList[i];

                    if (this._userList.containsKey(key_))
                    {

                            IUserModel user = (IUserModel)this._userList.get(key_);

                            int userMinute = user.getHeartTime();
                            boolean userHeartDead = true;

                            //------------ range check begin  -------------------

                            for (int j = 0; j < jLen; j++)
                            {
                                    if (userMinute == nowMinuteList.get(j))
                                    {
                                            userHeartDead = false;
                                            break;
                                    }

                            }

                            //------------ range check end ------------------

                            if (userHeartDead)
                            {
                                    deadList.add(key_.toString());
                            }
                            else
                            {
                                    healthList.add(key_.toString());
                            }



                    } //end if

            } //end foreach

            if (isDead)
            {
                    return deadList;
            }

            return healthList;
    }
    
    /** 
     这里的add调用前要加逻辑判断，不像session那样可以直接add
     已在线，需要先挤掉

     @param strIpPort
     @param user
    */
    public final void addUser(String strIpPort, IUserModel user)
    {

            
            _userList.put(strIpPort, user);

    }

    /** 


     @param strIpPort
    */
    public final void removeUser(String strIpPort)
    {
            if (_userList.containsKey(strIpPort))
            {
                    _userList.remove(strIpPort);
            }
    }

    /** 


     @param strIpPort
     @return 
    */
    public final boolean hasUser(String strIpPort)
    {
            return this._userList.containsKey(strIpPort);
    }
    
    public final int getUserCount()
    {
            return this._userList.size();
    }
    
    public final int getMaxOnlineUserConfig()
    {
            return this._maxOnlinePeople;
    }
    
    
}
